package com.hc.kotlin_coroutine

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.newSingleThreadContext
import kotlinx.coroutines.runBlocking
import kotlin.system.measureTimeMillis

fun main14() = runBlocking<Unit> {
//    val time = measureTimeMillis {
//        println("result = ${asyncSum()}")
//    }
//    println("time = ${time}")

    try {
        asyncSumFail()
    }catch (e:Exception){
        println(e)
    }
}
suspend fun asyncSum():Int = coroutineScope {
    val one = async { doOne() }
    val two = async { doTwo() }
    one.await()+two.await()
}
suspend fun asyncSumFail():Int = coroutineScope {
    val one = async {
        try {
            delay(10000)
            15
        }finally {
            println("async finally")
        }
    }
    val two = async<Int>{//协程抛异常导致其他协程也取消
        throw NullPointerException()
    }
    one.await()+two.await()
}
fun doOneAsync() = GlobalScope.async {
    doOne()
}
fun doTwoAsync() = GlobalScope.async {
    doTwo()
}
//协程上下文包含一个协程调度器 它确定协程在哪个线程或哪些线程上执行
//可将协程限制在一个特定的线程执行,或线程池,或不受限的运行
fun main() = runBlocking<Unit> {//主协程
//    launch {//从runBlocking中承袭了协程上下文和调度器
//        println("work in thread ${Thread.currentThread().name}")
//        delay(500)
//        println("work in thread ${Thread.currentThread().name}")
//    }

//    launch(Dispatchers.Unconfined) {//适用于不消耗CPU时间的任务,或不更新UI的任务
//        println("Unconfined work in thread ${Thread.currentThread().name}")
//        delay(500)
//        println("Unconfined work in thread ${Thread.currentThread().name}")
//    }

//    launch(Dispatchers.Default) {//使用共享的后台线程池 与GlobalScope使用相同的调度器
//        println("Default work in thread ${Thread.currentThread().name}")
//    }

//    launch(newSingleThreadContext("MySingleThread")) {//为协程启动一个线程
//        println("Single work in thread ${Thread.currentThread().name}")
//    }

    var a = async {
        println("${Thread.currentThread().name} async a")
        10
    }
    var b = async {
        println("${Thread.currentThread().name} async b")
        20
    }
    println("${Thread.currentThread().name} result ${a.await()} ${b.await()}")
}